package com.agx.kotlinmvp.http

import android.content.Context
import com.agx.kotlinmvp.model.ResponseWrapper
import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import org.json.JSONException
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException

abstract class RequestCallback<T>(private val context: Context) : Observer<ResponseWrapper<T>> {
    abstract fun success(data: T)
    abstract fun failure(statusCode: Int, apiErrorModel: ApiErrorModel)

    private object Status {
        val SUCCESS = 200
    }

    override fun onSubscribe(d: Disposable) {
        //加载提示
    }

    override fun onNext(t: ResponseWrapper<T>) {
        if (t.code == Status.SUCCESS) {
            success(t.data)
            return
        }

        val apiErrorModel = ApiErrorModel(t.code, t.desc)
        failure(t.code, apiErrorModel)
    }

    override fun onComplete() {
        //加载完成
    }

    override fun onError(e: Throwable) {
        //加载完成
        if (e is HttpException) {
            val apiErrorModel: ApiErrorModel = when (e.code()) {
                ApiErrorType.INTERNAL_SERVER_ERROR.code ->
                    ApiErrorType.INTERNAL_SERVER_ERROR.getApiErrorModel(context)
                ApiErrorType.BAD_GATEWAY.code ->
                    ApiErrorType.BAD_GATEWAY.getApiErrorModel(context)
                ApiErrorType.NOT_FOUND.code ->
                    ApiErrorType.NOT_FOUND.getApiErrorModel(context)
                ApiErrorType.CONNECTION_TIMEOUT.code ->
                    ApiErrorType.CONNECTION_TIMEOUT.getApiErrorModel(context)
                ApiErrorType.NETWORK_NOT_CONNECT.code ->
                    ApiErrorType.NETWORK_NOT_CONNECT.getApiErrorModel(context)
                ApiErrorType.NOT_LOGIN.code ->
                    ApiErrorType.NOT_LOGIN.getApiErrorModel(context)
                ApiErrorType.SERVICE_FORBIDDEN.code ->
                    ApiErrorType.SERVICE_FORBIDDEN.getApiErrorModel(context)
                else -> ApiErrorType.UNEXPECTED_ERROR.getApiErrorModel(context)

            }
            failure(e.code(), apiErrorModel)
            return
        }

        val apiErrorType: ApiErrorType = when (e) {
            is UnknownHostException -> ApiErrorType.NETWORK_NOT_CONNECT
            is ConnectException -> ApiErrorType.NETWORK_NOT_CONNECT
            is SocketTimeoutException -> ApiErrorType.CONNECTION_TIMEOUT
            is JsonSyntaxException -> ApiErrorType.JSON_ERROR
            else -> ApiErrorType.UNEXPECTED_ERROR
        }
        failure(apiErrorType.code, apiErrorType.getApiErrorModel(context))
    }

    private fun otherError(e: HttpException) =
            Gson().fromJson(e.response().errorBody()?.charStream(), ApiErrorModel::class.java)
}
